package com.cyj.dream.core.aspect;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.cyj.dream.core.aspect.annotation.log.LogRecord;
import com.cyj.dream.core.aspect.annotation.log.SysOperationLog;
import com.cyj.dream.core.exception.BizException;
import com.cyj.dream.core.util.IsEmptyUtils;
import com.cyj.dream.core.util.http.useragent.UserAgentUtils;
import com.cyj.dream.core.util.ip.IpToAddressUtil;
import com.cyj.dream.core.util.ip.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * The type Logs aspect.
 *
 * @Description: 日志操作记录
 * @BelongsProject: DreamChardonnay
 * @BelongsPackage: com.cyj.dream.admin.aspect
 * @Author: ChenYongJia
 * @CreateTime: 2021-4-2 09:41:14
 * @Email chen87647213 @163.com
 * @Version 1.0
 */
@Slf4j
@Aspect
@Component
public class LogsAspect {

    /**
     * 配置织入点 com.cyj.dream.admin.aspect.annotation.log.LogRecord
     */
    @Pointcut("@annotation(com.cyj.dream.core.aspect.annotation.log.LogRecord)")
    public void logPointCut() {
        log.info("logEntityPointCut");
    }

    /**
     * 环绕通知 用于拦截操作
     *
     * @param point the point
     * @return the object
     * @throws Throwable
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object result = point.proceed();
        saveLogEntity(point, result);
        return result;
    }

    /**
     * Save log entity.
     *
     * @param joinPoint the join point
     * @param result    the result
     */
    protected void saveLogEntity(ProceedingJoinPoint joinPoint, Object result) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysOperationLog logEntity = new SysOperationLog();
        try {
            //获得用户信息并记录到日志操作日志上
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = servletRequestAttributes.getRequest();

            // 获得注解上的描述并记录到日志操作日志上
            LogRecord logRecord = method.getAnnotation(LogRecord.class);

            // 操作者id先写死
            logEntity.setLogOperatorUserId((long) 1);
            // 设置模块
            logEntity.setLogOperatorContent(logRecord.title());
            // 设置操作类型
            logEntity.setLogOperatorType(logRecord.operatetype().getReasonPhrase());
            // 记录操作人ip地址
            logEntity.setLogOperatorIp(IpUtils.getIpAddr(request));
            // 腾讯地图获得到的ip地址信息
            StringBuffer address = IpToAddressUtil.getCityInfo(IpUtils.getIpAddr(request));

            String add = "";
            if(StrUtil.isNotEmpty(address)){
                add = address.toString();
                String[] array = add.split("-");
                // 国家
                if (!IsEmptyUtils.isEmpty(array[0])) {
                    logEntity.setLogOperatorNation(array[0]);
                }
                // 省份
                if (!IsEmptyUtils.isEmpty(array[1])) {
                    logEntity.setLogOperatorProvince(array[1]);
                }
                // 城市
                if (!IsEmptyUtils.isEmpty(array[2])) {
                    logEntity.setLogOperatorCity(array[2]);
                }
                if(array.length >= 4){
                    // 地区
                    if (!IsEmptyUtils.isEmpty(array[3])) {
                        logEntity.setLogOperatorArea(array[3]);
                    }
                }
            } else {
                add = "127.0.0.1";
                String[] array = add.split("-");
                // 国家
                if (!IsEmptyUtils.isEmpty(array[0])) {
                    logEntity.setLogOperatorNation(array[0]);
                }
            }

            // 获得请求的类名
            logEntity.setLogOperatorClassName(joinPoint.getTarget().getClass().getName());
            // 获得请求方法名
            logEntity.setLogOperatorMethodName(signature.getName());
            // 请求路径
            logEntity.setLogOperatorPath(request.getRequestURL().toString());
            // 记录请求方式
            logEntity.setLogOperatorRequestType(request.getMethod());
            // 记录浏览器名称
            logEntity.setLogOperatorBrowser(UserAgentUtils.getBrowserName(request));
            // 记录设备名称
            logEntity.setLogOperatorSystem(UserAgentUtils.getSystemName(request));
            if(!IsEmptyUtils.isEmpty(UserAgentUtils.getBrowserName(request)) && !IsEmptyUtils.isEmpty(UserAgentUtils.getVersion(request))){
                // 获得浏览器版本
                logEntity.setLogOperatorBrowserVersion(UserAgentUtils.getBrowserName(request) + "-" + UserAgentUtils.getVersion(request).toString());
            }
            //调用执行目标方法
            HttpServletResponse response = servletRequestAttributes.getResponse();
            // 记录请求结果
            logEntity.setLogOperatorResults("status:" + response.getStatus());
            // 保存操作日志对象
            HttpResponse response2 = HttpRequest.post("http://localhost:8166/pc/log/addOperationLog ")
                    .contentType("application/json")
                    .body(JSONObject.toJSONString(logEntity))
                    .execute();
            String result2 = response2.body();
            JSONObject obj = JSONObject.parseObject(result2);
        } catch (Exception e) {
            log.error("记录操作日志失败，原因为：{}", e);
            throw new BizException(e.toString());
        }
    }

}
